package com.s666.demo.config;

import com.s666.demo.exception.VerifyException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

/**
 * @author: 刘宏伟
 * @date: 2018/8/23 18:03
 * @description:
 */
@Component
@Slf4j
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    @Qualifier("webUserDetailsService")
    UserDetailsService userDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        //1. 初始化
        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication;
        CustomWebAuthenticationDetails details = (CustomWebAuthenticationDetails) authentication.getDetails();

        //2. 验证码校验
        if(!details.verify()) {
           throw new VerifyException("1000","验证码错误");
        }

        //3. 用户校验
        UserDetails userDetails = getByUsername(token.getName());
        if(userDetails == null){
            throw new VerifyException("1001","用户不存在");
        }

        //4. 密码校验
        String presentedPassword = token.getCredentials().toString();
        if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())){
            throw new VerifyException("1002","密码错误");
        }
        return new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities());

    }

    /**
     * 获取 userdetail
     * @param userName
     * @return
     */
    private UserDetails getByUsername(String userName){
        UserDetails userDetails = null;
        try {
            userDetails = userDetailsService.loadUserByUsername(userName);
            return userDetails;
        }catch(UsernameNotFoundException e){
            return null;
        }
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}
